package com.teng.dataStructure.LinkedList;

public class SingleLinkedListDemo {
    public static void main(String[] args) {

        HeroNode hero1 = new HeroNode(1, "菲奥娜", "剑姬");
        HeroNode hero2 = new HeroNode(3, "瑞兹", "光头");
        HeroNode hero3 = new HeroNode(7, "易大师", "剑圣");
        HeroNode hero4 = new HeroNode(4, "娜美", "人鱼");

        SingleLinkedList linkedList = new SingleLinkedList();
//        linkedList.add(hero1);
//        linkedList.add(hero2);
//        linkedList.add(hero3);
//        linkedList.add(hero4);
        linkedList.addByOrder(hero1);
        linkedList.addByOrder(hero2);
        linkedList.addByOrder(hero3);
        linkedList.addByOrder(hero4);
        linkedList.list();

        System.out.println("链表有效个数为：" + linkedList.number());

        int index = 2;
        System.out.println("倒数第" + index + "个节点为：" + linkedList.getHero(index));

        linkedList.delete(3);

        linkedList.update(new HeroNode(7, "易大师", "GG"));
        linkedList.list();
    }
}

//定义SingleLinkedlist 管理我们的英雄
class SingleLinkedList {
    //初始化头节点
    private HeroNode head = new HeroNode(0, "", "");
    //添加节点到单向节点
    //当不考虑编号的顺序时，找到当前链表的最后节点，将最后这个节点测next指向新节点
    public void add(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
            if (temp.getNext() == null) {
                break;
            }
            temp = temp.getNext();
        }
        //找到最后节点后，将hereNode加入next
        temp.setNext(heroNode);
    }

    //添加节点并自动排序
    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
            if (temp.getNext() == null) {//到了链表最后一个
                temp.setNext(heroNode);
                System.out.println(heroNode.getName() + "插入成功");
                break;
            }
            else if (heroNode.getNo() == temp.getNext().getNo()) {//已经有了相同编号
                System.out.println("已有相同编号:" + heroNode.getNo() + "，无法覆盖添加");
                break;
            }
            else if (heroNode.getNo() < temp.getNext().getNo()) {//插入数据的编号小于当前节点的下一节点的编号，找到了位置
                heroNode.setNext(temp.getNext());
                temp.setNext(heroNode);
                System.out.println(heroNode.getName() + "插入成功");
                break;
            }
            else {
                temp = temp.getNext();
            }
        }
    }

    //节点删除
    public void delete(int no) {
        HeroNode temp = head;
        while (true) {
            //首次判断：是否为空链表；后面判断的都是尾部，如果到尾部还没有进入到else if中说明链表中不存在该编号
            if (temp.getNext() == null) {
                System.out.println("链表中无编号为：" + no);
                break;
            }
            else if (temp.getNext().getNo() == no) {
                if (temp.getNext().getNext() != null) {
                    temp.setNext(temp.getNext().getNext());
                    break;
                }
                temp.setNext(null);
                break;
            }
            else { temp = temp.getNext(); }
        }
    }

    //节点修改
    public void update(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
            if (temp.getNext() == null) {
                System.out.println("链表中无编号为：" + heroNode.getNo());
                break;
            }
            else if (temp.getNext().getNo() == heroNode.getNo()) {
                if (temp.getNext().getNext() != null) {
                    heroNode.setNext(temp.getNext().getNext());
                    temp.setNext(heroNode);
                    break;
                }
                temp.setNext(heroNode);
                break;
            }
            else { temp = temp.getNext(); }
        }
    }

    //显示链表
    public void list(){
        HeroNode temp = head;
        if (temp.getNext() == null){

        }
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.getNext();
        }
    }

    //求单链表中有效节点的个数
    public int number(){
        int count = 0;
        HeroNode temp = head;
        while (true) {
            if (temp.getNext() == null) {
                break;
            }
            count++;
            temp = temp.getNext();
        }
        return count;
    }

    //求单链表的倒数第K个节点
    public HeroNode getHero(int index) {
        HeroNode temp = head;
        int length = number();
        index  = length -index;
        while (index >= 0) {
            temp = temp.getNext();
            index--;
        }
        return  temp;
    }
}

//定义heroNode，每个heroNode就是一个节点
class HeroNode {
    //定义英雄属性
    private int no;
    private String name;
    private String nickName;
    private HeroNode next;

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public HeroNode getNext() {
        return next;
    }

    public void setNext(HeroNode next) {
        this.next = next;
    }

    //构造器
    public HeroNode() {
    }

    public HeroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    //重写toString便于展示
    @Override
    public String toString() {
        return "HeroNode{" + "no=" + no + ", name=" + name + ", nickName=" + nickName + '}';
    }
}
